{ 本程序用于执行多版本脚本 }

{ 设置程序类型，
  详见：http://www.freepascal.org/docs-html/prog/progsu86.html }

{ 该指令目前仅支持以下目标：Win32，Mac，OS2和AmigaOS。在其他目标上，该指令被忽略。 }
{$ifdef Windows OR MAC OR OS2 OR AMIGAOS}
{$APPTYPE CONSOLE}
{$endif}

{ 设置编译器模式，
  详见：http://www.freepascal.org/docs-html/prog/progsu105.html }
{$MODE objfpc}

{ 设置处理 IO 错误
  详见：http://wiki.freepascal.org/File_Handling_In_Pascal/zh_CN

  它告诉编译器如何处理IO错误：抛出一个异常或将结果存储到IOResult变量。
  i+ 将 异常信息存入 EInOutError 中，使用 try E:EInOutError except 来处理这个异常
  则 E.ClassName 异常类型 E.Message 异常说明

  i- 将 错误编号存入 IOResult 变量
  错误编号及说明详见；http://www.freepascal.org/docs-html/rtl/system/ioresult.html
}

{$I+}

{ 定义程序名称 }
program exec;

{ 定义引用单元 }
uses
  Classes,
  SysUtils,
  Strings,
  inifiles,
  Process;

var
  i, paramNum: integer; { for i 变量和参数数量 }
  exeType: ansistring;{执行脚本类型}
  paramList: ansistring; { 用于脚本参数 }
  confObj: TINIFile; { INI 文件对象 }
  exeFile: ansistring;{执行脚本路径}
  iniFile: ansistring; {INI 配置文件路径}


  { 程序介绍 aboutMe过程() }
  procedure aboutMe();
  begin

    writeln('exec, Used to execute different versions of the program.');
    writeln();
    writeln('Usage:');
    writeln('exec <type> [param]');
    writeln();
    writeln('Example:');
    writeln('exec php5 index.php');
    writeln('exec php5r echo 1;');
    writeln();
    writeln('exec.ini file example:');
    writeln('	[php5]');
    writeln('	path = D:\php5\php');
    writeln('	[php5r]');
    writeln('	path = D:\php5\php -r "%s"');
    writeln('	[path7]');
    writeln('	path = D:\php7\php');
    writeln('	[path7r]');
    writeln('	path = D:\php7\php -r "%s"');
    writeln('	...');
    writeln();
  end;


begin

  { 传递参数解析 }
  paramList := '';
  paramNum := ParamCount();
  iniFile := ExtractFileDir(ParamStr(0)) + DirectorySeparator + 'exec.ini';

  // 参数数量为 0 显示程序说明
  if (paramNum = 0) then
  begin
    aboutMe();
    exit;
  end;

  exeType := ParamStr(1);

  i := 2;
  while (i <= paramNum) do
  begin
    paramList := paramList + ' ' + ParamStr(i);
    Inc(i);
  end;


{ 跨平台编程注意事项
  详见：http://wiki.freepascal.org/Multiplatform_Programming_Guide/zh_CN }

  if (not FileExists(iniFile)) then
  begin
    writeln(iniFile + ' file does not exist, please create it.');
    exit;
  end;

  confObj := TINIFile.Create(iniFile);
  exeFile := confObj.Readstring(exeType, 'file', '');


  // 如果配置项为 0 则表明无效配置文件
  if (exeFile = '') then
  begin
    writeln(Format('%s configuration item does not exist.', [exeType]));
    exit;
  end;

  exeFile := StringReplace(exeFile, '%s', paramList, []);

  // 命令行参数 " 空格问题会被过滤和分隔
  // 内置就是如此
  ExecuteProcess(exeFile, paramList);

end.
